# -*- coding: utf-8 -*-
# @Time : 2021/05/24
# @Author : ricky
# @File : deletefile.py
# @Software: vscode
"""删除指定路径下指定的文件或者文件夹"""
import wx
import os
import shutil
import threading
from . import filedel_dialog as dialog
from loguru import logger
from pathlib import Path


class FileDel(dialog.FileDelDialog):
    def __init__(self, parent):
        dialog.FileDelDialog.__init__(self, parent)
        self.m_dirPicker.GetPickerCtrl().SetLabel('选择目录')
        self.m_dirPicker.GetTextCtrl().SetHint('请选择要删除文件或者文件夹的根目录')
        self.m_gauge.Hide()
        self.Centre()

    def OnClickEventDelete(self, event):
        """删除按钮事件"""
        selectpath = self.m_dirPicker.GetPath()
        if len(selectpath) == 0:
            self.show_message('请选择目录')
            return
        if os.path.exists(selectpath) is False:
            self.show_message('选择的目录不存在')
            return
        input_file_or_dir = self.m_text_ctrl_input_file_or_dir.GetValue()
        if len(input_file_or_dir) != 0:
            if input_file_or_dir.find('\uff1b') != -1:
                self.show_message('检测到输入的分号为中文符号，请检查')
                return
        # 选中的添加到列表中
        delfiles = set()
        if self.m_check_box_dot_settings.IsChecked():
            delfiles.add(self.m_check_box_dot_settings.GetLabelText())
        if self.m_check_box_dir_target.IsChecked():
            delfiles.add(self.m_check_box_dir_target.GetLabelText())
        if self.m_check_box_dot_classpath.IsChecked():
            delfiles.add(self.m_check_box_dot_classpath.GetLabelText())
        if self.m_check_box_dot_project.IsChecked():
            delfiles.add(self.m_check_box_dot_project.GetLabelText())
        if self.m_check_box_dot_idea.IsChecked():
            delfiles.add(self.m_check_box_dot_idea.GetLabelText())
        if self.m_check_box_mac_MACOSX.IsChecked():
            delfiles.add(self.m_check_box_mac_MACOSX.GetLabelText())
        if self.m_check_box_dot_iml.IsChecked():
            delfiles.add(self.m_check_box_dot_iml.GetLabelText())
        if self.m_check_box_mac_dot_.IsChecked():
            delfiles.add(self.m_check_box_mac_dot_.GetLabelText())
        if self.m_check_box_mac_dot_DS_Store.IsChecked():
            delfiles.add(self.m_check_box_mac_dot_DS_Store.GetLabelText())
        if self.m_check_box_node_modules.IsChecked():
            delfiles.add(self.m_check_box_node_modules.GetLabelText())
        for fd in input_file_or_dir.split(';'):
            if len(fd):
                delfiles.add(fd)
        if len(delfiles) == 0:
            return '没有要删除的文件或者文件夹'
        dlg = wx.MessageDialog(None, '确认开始删除吗？删除后不可恢复，请确认是否已经备份！', '操作提醒',
                               wx.YES_NO)
        if dlg.ShowModal() == wx.ID_YES:
            dlg.Destroy()
            t = threading.Thread(target=self.del_task,
                                 args=(selectpath, delfiles))
            t.start()

    def del_task(self, selectpath, deltarget):
        """
        删除任务

        参数:
            selectpath (str): 选择的根目录
            deltarget (set): 删除目标集合（用做匹配）
        """
        try:
            self.m_dirPicker.Disable()
            self.m_text_ctrl_input_file_or_dir.Disable()
            self.m_button_delete.Disable()
            self.m_button_reset.Disable()
            self.m_text_log.Clear()
            self.show_operate_log('匹配文件中，请稍后...')
            # 先匹配文件和文件夹
            files = []
            self.match_files(selectpath, deltarget, files)
            if (len(files) > 0):
                self.rmfile(files)
                self.show_operate_log('文件删除完成！')
            else:
                self.show_operate_log('没有匹配到要删除的文件！')
        finally:
            self.m_dirPicker.Enable()
            self.m_text_ctrl_input_file_or_dir.Enable()
            self.m_button_delete.Enable()
            self.m_button_reset.Enable()

    def match_files(self, dir, deltarget, files=[]):
        """
        匹配的文件和文件夹

        参数:
            dir (str): 递归目录全路径
            deltarget (set): 删除目标集合（用做匹配）
            files(list): 匹配到的结果
        """
        fns = os.listdir(dir)
        for fn in fns:
            joinpath = os.path.join(dir, fn)
            if os.path.isfile(joinpath):
                if fn in deltarget or os.path.basename(joinpath) in deltarget or Path(fn).suffix in deltarget:
                    files.append(joinpath)
            else:
                if fn in deltarget:
                    files.append(joinpath)
                else:
                    self.match_files(joinpath, deltarget, files)

    def rmfile(self, files):
        """
        文件删除

        参数:
            files (list): 要删除的文件集合
        """
        for i, file in enumerate(files):

            try:
                if os.path.isfile(file):
                    os.remove(file)
                    ftype = "文件"
                else:
                    shutil.rmtree(file)
                    ftype = "文件夹"
                status = "成功"
            except OSError as err:
                logger.error('删除{}：{} {}', ftype, file, err)
                status = "异常"
            finally:
                logger.info('删除{}：{} {}', ftype, file, status)
                self.show_operate_log(
                    '删除' + ftype + '：-------------\n' + file + '\n【' + status + "】")

                self.update_progress(round((i + 1)/len(files) * 100))

    def show_operate_log(self, log):
        """
        统一显示日志到控件

        参数:
            self (object): 当前对象
            log (str): 日志内容
        """
        # 这里要在主线程更新UI，否则会报错
        wx.CallAfter(self.m_text_log.AppendText, log + '\n')
        self.m_text_log.ShowPosition(self.m_text_log.GetLastPosition())

    def update_progress(self, pos=0):
        """
        更新进度条

        参数:
            self (object): 当前对象
            pos (Number): 进度条位置（0-100）
        """
        wx.CallAfter(self.m_gauge.SetValue, pos)
        if (pos == 100):
            if (self.m_gauge.IsShown()):
                wx.CallAfter(self.m_gauge.SetValue, 0)
                self.m_gauge.Hide()
        else:
            if (not self.m_gauge.IsShown()):
                self.m_gauge.Show()

    def show_message(self, message):
        """
        统一显示对话框

        参数:
            message (str): 对话框内容
        """
        wx.MessageDialog(None, message, '操作提醒', wx.OK).ShowModal()

    def OnClickEventReset(self, event):
        """重置按钮事件"""
        self.m_dirPicker.SetPath('')
        self.m_text_ctrl_input_file_or_dir.SetValue('')
        self.m_text_log.SetValue('')
